package com.zycfc.zsf.boot.office.excel;

import com.zycfc.zsf.boot.exception.*;
import com.zycfc.zsf.boot.office.excel.constant.*;
import com.zycfc.zsf.boot.util.text.*;
import com.monitorjbl.xlsx.*;
import org.apache.poi.openxml4j.exceptions.*;
import java.text.*;
import java.io.*;
import org.apache.poi.poifs.filesystem.*;
import com.zycfc.zsf.boot.util.collection.*;
import com.zycfc.zsf.boot.office.excel.bean.*;
import com.monitorjbl.xlsx.impl.*;
import java.lang.reflect.*;
import java.math.*;
import com.zycfc.zsf.boot.util.time.*;
import java.awt.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.hssf.util.*;
import org.apache.poi.hssf.usermodel.*;
import org.hibernate.validator.*;
import javax.validation.*;
import java.util.*;
import org.slf4j.*;

public class ExcelUtil
{
    private static final Logger log;
    private static final String EXCEL_FILE = "\u4f20\u5165\u7684excel\u6587\u4ef6";
    private static final String EXCEL_2003_SUFFIX = "xls";
    private static final String EXCEL_2007_SUFFIX = "xlsx";
    private static final String NOT_SUPPORT_FILE = "\u4e0d\u652f\u6301\u7684\u6587\u4ef6\u7c7b\u578b\uff01";
    private static final String EXCEL_SHEET_NO = "excel sheet\u53f7";
    private static final String EXCEL_START_NO = "excel \u8d77\u59cb\u884c\u53f7";
    private static final String EXCEL_TABLE_HEAD = "excel\u8868\u5934";
    private static final String CELL_IS_NULL = "\u4e2d\u5b58\u5728\u7a7a\u7684\u5355\u5143\u683c\uff1a";
    private static final String EXCEL_COLUMN_COUNT_NOT_MATCH_COLUMNINDEXMAP = "excel\u6587\u4ef6\u91cc\u5217\u6570\u8ddf\u5165\u53c2\u7684\u5217\u6570\u4e0d\u4e00\u81f4\uff01";
    private static final String EXCEL_HEAD_FONT_NAME = "\u9ed1\u4f53";
    private static final String EXCEL_BODY_FONT_NAME = "\u5b8b\u4f53";
    private static final String PARAM_COLLECTION_IS_NULL = "\u4f20\u5165\u7684\u6570\u636e\u96c6\u5408\u4e3a\u7a7a\uff01";
    private static final String GET_METHOD_PRE = "get";
    private static final String SET_METHOD_PRE = "set";
    private static final String COLUMNHEADMAP_COUNT_NOT_MATCH_COLUMINDEXMAP = "\u4f20\u5165\u8868\u5934\u5217\u6570\u548c\u5b9e\u4f53\u5c5e\u6027\u4e2a\u6570\u4e0d\u4e00\u81f4\uff01";
    private static final String PARAM_BYTE_ARRAY_IS_NULL = "\u4f20\u5165\u7684\u5b57\u8282\u6570\u7ec4\u4e3a\u7a7a\uff01";
    private static final String ASSEMBLE_PARSE_EXCEPTION_ERROR = "\u62fc\u88c5\u7b2c{}\u884c\u5f02\u5e38\u4fe1\u606f\u53d1\u751fException:";
    
    public static <T> List<T> parseExcel(final File excelFile, final Class<T> tCls, final ExcelModel excelModel) throws Exception {
        checkFile(excelFile);
        checkExcelModel(excelModel);
        final List<ExcelColumnModel> excelColumnModelList = excelModel.getExcelColumnModelList();
        Collections.sort(excelColumnModelList);
        List<T> list = null;
        try {
            list = (List<T>)(excelFile.getName().endsWith("xlsx") ? readXlsx(excelFile, (Class<Object>)tCls, excelModel) : readXls(excelFile, (Class<Object>)tCls, excelModel));
        }
        catch (NotOfficeXmlFileException e) {
            throw new ServiceException((IExceptionCode)OfficeExceptionCode.ERROR2008);
        }
        return list;
    }
    
    public static <T> void parseXlsx(final File excelFile, final Class<T> tCls, final ExcelModel excelModel, final IExcelHandler handler) throws Exception {
        checkXlsxFile(excelFile);
        checkExcelModel(excelModel);
        final List<ExcelColumnModel> excelColumnModelList = excelModel.getExcelColumnModelList();
        Collections.sort(excelColumnModelList);
        try {
            readXlsx(excelFile, (Class<Object>)tCls, excelModel, handler);
        }
        catch (NotOfficeXmlFileException e) {
            throw new ServiceException((IExceptionCode)OfficeExceptionCode.ERROR2008);
        }
    }
    
    public static <T> List<T> parseExcel(final byte[] excelBytes, final ExcelConstant.ExcelTypeEnum excelType, final Class<T> tCls, final ExcelModel excelModel) throws Exception {
        CheckUtil.notEmpty((Object)excelBytes, "\u4f20\u5165\u7684\u5b57\u8282\u6570\u7ec4\u4e3a\u7a7a\uff01");
        checkExcelModel(excelModel);
        final List<ExcelColumnModel> excelColumnModelList = excelModel.getExcelColumnModelList();
        Collections.sort(excelColumnModelList);
        List<T> list = null;
        try {
            list = (ExcelConstant.ExcelTypeEnum.EXCEL2007.equals(excelType) ? readXlsxBytes(excelBytes, tCls, excelModel) : readXlsBytes(excelBytes, tCls, excelModel));
        }
        catch (NotOfficeXmlFileException e) {
            throw new ServiceException((IExceptionCode)OfficeExceptionCode.ERROR2008);
        }
        return list;
    }
    
    public static <T> ExcelParseResultModel parse(final File excelFile, final Class<T> tCls, final ExcelModel excelModel) throws Exception {
        checkFile(excelFile);
        checkExcelModel(excelModel);
        final List<ExcelColumnModel> excelColumnModelList = excelModel.getExcelColumnModelList();
        Collections.sort(excelColumnModelList);
        return excelFile.getName().endsWith("xlsx") ? parseXlsx(excelFile, (Class<Object>)tCls, excelModel) : parseXls(excelFile, (Class<Object>)tCls, excelModel);
    }
    
    public static <T> ExcelParseResultModel parse(final byte[] excelBytes, final ExcelConstant.ExcelTypeEnum excelType, final Class<T> tCls, final ExcelModel excelModel) throws Exception {
        CheckUtil.notEmpty((Object)excelBytes, "\u4f20\u5165\u7684\u5b57\u8282\u6570\u7ec4\u4e3a\u7a7a\uff01");
        checkExcelModel(excelModel);
        final List<ExcelColumnModel> excelColumnModelList = excelModel.getExcelColumnModelList();
        Collections.sort(excelColumnModelList);
        return ExcelConstant.ExcelTypeEnum.EXCEL2007.equals(excelType) ? parseXlsxBytes(excelBytes, tCls, excelModel) : parseXlsBytes(excelBytes, tCls, excelModel);
    }
    
    public static <T> void toExcel(final OutputStream out, final String title, final Collection<T> dataCollection, final ExcelConstant.ExcelTypeEnum excelType, final ExcelModel excelModel) throws Exception {
        CheckUtil.notEmpty((Object)dataCollection, "\u4f20\u5165\u7684\u6570\u636e\u96c6\u5408\u4e3a\u7a7a\uff01");
        checkExcelModel(excelModel);
        final List<ExcelColumnModel> excelColumnModelList = excelModel.getExcelColumnModelList();
        Collections.sort(excelColumnModelList);
        switch (excelType) {
            case EXCEL2007: {
                toExcel2007(out, title, dataCollection, excelModel);
                break;
            }
            case EXCEL2003: {
                toExcel2003(out, title, dataCollection, excelModel);
                break;
            }
            default: {
                throw new IllegalArgumentException("\u4e0d\u652f\u6301\u7684\u6587\u4ef6\u7c7b\u578b\uff01");
            }
        }
    }
    
    public static <T> byte[] toExcelBytes(final String title, final Collection<T> dataCollection, final ExcelConstant.ExcelTypeEnum excelType, final ExcelModel excelModel) throws Exception {
        final ByteArrayOutputStream out = new ByteArrayOutputStream();
        toExcel(out, title, dataCollection, excelType, excelModel);
        out.flush();
        return out.toByteArray();
    }
    
    private static void checkFile(final File excelFile) {
        CheckUtil.notNull((Object)excelFile, "\u4f20\u5165\u7684excel\u6587\u4ef6");
        final String excelFileName = excelFile.getName();
        if (excelFileName.endsWith("xls") || excelFileName.endsWith("xlsx")) {
            return;
        }
        throw new IllegalArgumentException("\u4e0d\u652f\u6301\u7684\u6587\u4ef6\u7c7b\u578b\uff01");
    }
    
    private static void checkXlsxFile(final File excelFile) {
        CheckUtil.notNull((Object)excelFile, "\u4f20\u5165\u7684excel\u6587\u4ef6");
        final String excelFileName = excelFile.getName();
        if (excelFileName.endsWith("xlsx")) {
            return;
        }
        throw new IllegalArgumentException("\u4e0d\u652f\u6301\u7684\u6587\u4ef6\u7c7b\u578b\uff01");
    }
    
    private static void checkExcelModel(final ExcelModel excelModel) {
        CheckUtil.notNull((Object)excelModel.getSheetNo(), "excel sheet\u53f7");
        CheckUtil.notNull((Object)excelModel.getStartRowNo(), "excel \u8d77\u59cb\u884c\u53f7");
        CheckUtil.notNull((Object)excelModel, "excel\u8868\u5934");
        final List<ExcelColumnModel> excelColumnModelList = excelModel.getExcelColumnModelList();
        CheckUtil.notEmpty((Object)excelColumnModelList, "excel\u8868\u5934");
    }
    
    private static <T> List<T> readXlsx(final File excelFile, final Class<T> tCls, final ExcelModel excelMode) throws IOException, InvalidFormatException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException, NoSuchFieldException, ParseException {
        Workbook book = null;
        try {
            book = (Workbook)new XSSFWorkbook(excelFile);
            final Workbook wk = StreamingReader.builder().rowCacheSize(100).open(excelFile);
            final Sheet sheet = book.getSheetAt((int)excelMode.getSheetNo());
            return read(sheet, book, tCls, excelMode, excelMode.getStartRowNo(), getStartColNo(excelMode, ExcelConstant.ExcelTypeEnum.EXCEL2007));
        }
        catch (Exception e) {
            throw e;
        }
        finally {
            if (book != null) {
                book.close();
            }
        }
    }
    
    private static <T> void readXlsx(final File excelFile, final Class<T> tCls, final ExcelModel excelMode, final IExcelHandler handler) throws IOException, InvalidFormatException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException, NoSuchFieldException, ParseException {
        Workbook book = null;
        try {
            book = StreamingReader.builder().rowCacheSize(100).open(excelFile);
            final Sheet sheet = book.getSheetAt((int)excelMode.getSheetNo());
            readContent(sheet, book, tCls, excelMode, excelMode.getStartRowNo(), getStartColNo(excelMode, ExcelConstant.ExcelTypeEnum.EXCEL2007), handler);
        }
        catch (Exception e) {
            throw e;
        }
        finally {
            if (book != null) {
                book.close();
            }
        }
    }
    
    private static <T> ExcelParseResultModel parseXlsx(final File excelFile, final Class<T> tCls, final ExcelModel excelMode) throws IOException, InvalidFormatException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException, NoSuchFieldException, ParseException {
        Workbook book = null;
        try {
            book = (Workbook)new XSSFWorkbook(excelFile);
            final Sheet sheet = book.getSheetAt((int)excelMode.getSheetNo());
            return parse(sheet, book, tCls, excelMode, excelMode.getStartRowNo(), getStartColNo(excelMode, ExcelConstant.ExcelTypeEnum.EXCEL2007));
        }
        catch (Exception e) {
            throw e;
        }
        finally {
            if (book != null) {
                book.close();
            }
        }
    }
    
    private static <T> List<T> readXlsxBytes(final byte[] excelBytes, final Class<T> tCls, final ExcelModel excelMode) throws IOException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException, NoSuchFieldException, ParseException {
        Workbook book = null;
        try {
            book = (Workbook)new XSSFWorkbook((InputStream)new ByteArrayInputStream(excelBytes));
            final Sheet sheet = book.getSheetAt((int)excelMode.getSheetNo());
            return read(sheet, book, tCls, excelMode, excelMode.getStartRowNo(), getStartColNo(excelMode, ExcelConstant.ExcelTypeEnum.EXCEL2007));
        }
        catch (Exception e) {
            throw e;
        }
        finally {
            if (book != null) {
                book.close();
            }
        }
    }
    
    private static <T> ExcelParseResultModel parseXlsxBytes(final byte[] excelBytes, final Class<T> tCls, final ExcelModel excelMode) throws IOException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException, NoSuchFieldException, ParseException {
        Workbook book = null;
        try {
            book = (Workbook)new XSSFWorkbook((InputStream)new ByteArrayInputStream(excelBytes));
            final Sheet sheet = book.getSheetAt((int)excelMode.getSheetNo());
            return parse(sheet, book, tCls, excelMode, excelMode.getStartRowNo(), getStartColNo(excelMode, ExcelConstant.ExcelTypeEnum.EXCEL2007));
        }
        catch (Exception e) {
            throw e;
        }
        finally {
            if (book != null) {
                book.close();
            }
        }
    }
    
    private static <T> List<T> readXls(final File excelFile, final Class<T> tCls, final ExcelModel excelMode) throws IOException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException, NoSuchFieldException, ParseException {
        POIFSFileSystem poifsFileSystem = null;
        try {
            poifsFileSystem = new POIFSFileSystem((InputStream)new FileInputStream(excelFile));
            final Workbook book = (Workbook)new HSSFWorkbook(poifsFileSystem);
            final Sheet sheet = book.getSheetAt((int)excelMode.getSheetNo());
            return read(sheet, book, tCls, excelMode, excelMode.getStartRowNo() + 1, getStartColNo(excelMode, ExcelConstant.ExcelTypeEnum.EXCEL2003));
        }
        catch (Exception e) {
            throw e;
        }
        finally {
            if (poifsFileSystem != null) {
                poifsFileSystem.close();
            }
        }
    }
    
    private static <T> ExcelParseResultModel parseXls(final File excelFile, final Class<T> tCls, final ExcelModel excelMode) throws IOException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException, NoSuchFieldException, ParseException {
        POIFSFileSystem poifsFileSystem = null;
        try {
            poifsFileSystem = new POIFSFileSystem((InputStream)new FileInputStream(excelFile));
            final Workbook book = (Workbook)new HSSFWorkbook(poifsFileSystem);
            final Sheet sheet = book.getSheetAt((int)excelMode.getSheetNo());
            return parse(sheet, book, tCls, excelMode, excelMode.getStartRowNo() + 1, getStartColNo(excelMode, ExcelConstant.ExcelTypeEnum.EXCEL2003));
        }
        catch (Exception e) {
            throw e;
        }
        finally {
            if (poifsFileSystem != null) {
                poifsFileSystem.close();
            }
        }
    }
    
    private static <T> List<T> readXlsBytes(final byte[] excelBytes, final Class<T> tCls, final ExcelModel excelMode) throws IOException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException, NoSuchFieldException, ParseException {
        POIFSFileSystem poifsFileSystem = null;
        try {
            poifsFileSystem = new POIFSFileSystem((InputStream)new ByteArrayInputStream(excelBytes));
            final Workbook book = (Workbook)new HSSFWorkbook(poifsFileSystem);
            final Sheet sheet = book.getSheetAt((int)excelMode.getSheetNo());
            return read(sheet, book, tCls, excelMode, excelMode.getStartRowNo() + 1, getStartColNo(excelMode, ExcelConstant.ExcelTypeEnum.EXCEL2003));
        }
        catch (Exception e) {
            throw e;
        }
        finally {
            if (poifsFileSystem != null) {
                poifsFileSystem.close();
            }
        }
    }
    
    private static <T> ExcelParseResultModel parseXlsBytes(final byte[] excelBytes, final Class<T> tCls, final ExcelModel excelMode) throws IOException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException, NoSuchFieldException, ParseException {
        POIFSFileSystem poifsFileSystem = null;
        try {
            poifsFileSystem = new POIFSFileSystem((InputStream)new ByteArrayInputStream(excelBytes));
            final Workbook book = (Workbook)new HSSFWorkbook(poifsFileSystem);
            final Sheet sheet = book.getSheetAt((int)excelMode.getSheetNo());
            return parse(sheet, book, tCls, excelMode, excelMode.getStartRowNo() + 1, getStartColNo(excelMode, ExcelConstant.ExcelTypeEnum.EXCEL2003));
        }
        catch (Exception e) {
            throw e;
        }
        finally {
            if (poifsFileSystem != null) {
                poifsFileSystem.close();
            }
        }
    }
    
    private static int getStartColNo(final ExcelModel excelMode, final ExcelConstant.ExcelTypeEnum excelType) {
        final Integer paramColNo = excelMode.getStartColNo();
        int startColNo = (CheckUtil.isNotNull((Object)paramColNo) && paramColNo >= 0) ? paramColNo : 0;
        startColNo = (ExcelConstant.ExcelTypeEnum.EXCEL2007.equals(excelType) ? startColNo : (startColNo + 1));
        return startColNo;
    }
    
    private static <T> List<T> read(final Sheet sheet, final Workbook book, final Class<T> tCls, final ExcelModel excelMode, final int startRowNo, final int startColNo) throws IOException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchFieldException, ParseException {
        final int firstRowNum = sheet.getFirstRowNum();
        final int lastRowNum = sheet.getLastRowNum();
        if (firstRowNum == lastRowNum) {
            book.close();
            return null;
        }
        final List<ExcelColumnModel> excelColumnModelList = excelMode.getExcelColumnModelList();
        final Row startRow = sheet.getRow(startRowNo);
        final int firstCellNo = startRow.getFirstCellNum();
        final int lastCellNo = startRow.getLastCellNum();
        final int columnCount = excelColumnModelList.size();
        final LinkedHashMap<Integer, Method> methodMap = getMethodMap(excelColumnModelList, tCls, "set");
        final List<T> list = new ArrayList<T>();
        for (int r = excelMode.getStartRowNo(); r <= lastRowNum; ++r) {
            final Row curRow = sheet.getRow(r);
            if (curRow == null) {
                break;
            }
            final T data = tCls.newInstance();
            final StringBuffer valBuffer = new StringBuffer();
            for (int c = firstCellNo; c < columnCount; ++c) {
                final Cell cell = curRow.getCell(c);
                if (cell != null) {
                    final String cellValue = getValue(cell);
                    if (!CheckUtil.isEmpty((Object)cellValue)) {
                        valBuffer.append(cellValue);
                        final Method method = methodMap.get(c);
                        invokeMethod(data, method, cellValue);
                    }
                }
            }
            if (valBuffer.toString().length() <= 0) {
                break;
            }
            list.add(data);
        }
        book.close();
        return list;
    }
    
    private static <T> void readContent(final Sheet sheet, final Workbook book, final Class<T> tCls, final ExcelModel excelMode, final int startRowNo, final int startColNo, final IExcelHandler handler) throws IOException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchFieldException, ParseException {
        final List<ExcelColumnModel> excelColumnModelList = excelMode.getExcelColumnModelList();
        final LinkedHashMap<Integer, Method> methodMap = getMethodMap(excelColumnModelList, tCls, "set");
        final List<T> dataList = new ArrayList<T>();
        int rowNum = 0;
        final long beginTime = System.currentTimeMillis();
        for (final Row row : sheet) {
            if (rowNum < startRowNo) {
                ++rowNum;
            }
            else {
                if (row == null) {
                    break;
                }
                final T data = tCls.newInstance();
                final StringBuffer valBuffer = new StringBuffer();
                for (final Cell cell : row) {
                    final int cellNum = cell.getColumnIndex();
                    if (cellNum < startColNo) {
                        continue;
                    }
                    if (cell == null) {
                        continue;
                    }
                    final String cellValue = getStreamCellValue(cell);
                    if (CheckUtil.isEmpty((Object)cellValue)) {
                        continue;
                    }
                    valBuffer.append(cellValue);
                    final Method method = methodMap.get(cellNum);
                    invokeMethod(data, method, cellValue);
                }
                if (dataList.size() == 100) {
                    handler.handle(dataList);
                    dataList.removeAll(dataList);
                }
                if (valBuffer.toString().length() <= 0) {
                    break;
                }
                dataList.add(data);
                ++rowNum;
            }
        }
        if (CollectionUtils.isNotEmpty((Collection)dataList)) {
            handler.handle(dataList);
        }
        ExcelUtil.log.info("\u672c\u6b21\u89e3\u6790excel\u5171\u8bfb\u53d6\u884c\u6570{},\u5171\u8017\u65f6{}\u6beb\u79d2", (Object)rowNum, (Object)(System.currentTimeMillis() - beginTime));
    }
    
    private static <T> ExcelParseResultModel parse(final Sheet sheet, final Workbook book, final Class<T> tCls, final ExcelModel excelMode, final int startRowNo, final int startColNo) throws IOException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchFieldException, ParseException {
        final int firstRowNum = sheet.getFirstRowNum();
        final int lastRowNum = sheet.getLastRowNum();
        if (firstRowNum == lastRowNum) {
            book.close();
            return null;
        }
        final List<ExcelColumnModel> excelColumnModelList = excelMode.getExcelColumnModelList();
        final Row startRow = sheet.getRow(startRowNo);
        final int firstCellNo = startRow.getFirstCellNum();
        final int lastCellNo = startRow.getLastCellNum();
        final int columnCount = excelColumnModelList.size();
        final ExcelParseResultModel resultModel = new ExcelParseResultModel();
        final LinkedHashMap<Integer, Method> methodMap = getMethodMap(excelColumnModelList, tCls, "set");
        final LinkedHashMap<String, String> colDescMap = getColumnDescMap(excelColumnModelList);
        final List<T> list = new ArrayList<T>();
        final List<ExcelParseExceptionModel> excepModelList = new ArrayList<ExcelParseExceptionModel>();
        for (int r = excelMode.getStartRowNo(); r <= lastRowNum; ++r) {
            final Row curRow = sheet.getRow(r);
            if (curRow == null) {
                break;
            }
            final T data = tCls.newInstance();
            final StringBuffer valBuffer = new StringBuffer();
            for (int c = firstCellNo; c < columnCount; ++c) {
                final Cell cell = curRow.getCell(c);
                if (cell != null) {
                    final String cellValue = getValue(cell);
                    if (!CheckUtil.isEmpty((Object)cellValue)) {
                        valBuffer.append(cellValue);
                        final Method method = methodMap.get(c);
                        invokeMethod(data, method, cellValue);
                    }
                }
            }
            if (valBuffer.toString().length() <= 0) {
                break;
            }
            list.add(data);
            validate(data, r, colDescMap, excepModelList);
        }
        book.close();
        resultModel.setDataList(list);
        resultModel.setExcepList(excepModelList);
        return resultModel;
    }
    
    private static String getValue(final Cell cell) {
        String cellValue = null;
        switch (cell.getCellType()) {
            case 1: {
                cellValue = cell.getStringCellValue();
                break;
            }
            case 0: {
                cell.setCellType(CellType.STRING);
                cellValue = cell.getStringCellValue();
                break;
            }
            case 2: {
                cellValue = cell.getStringCellValue();
                break;
            }
            case 4: {
                cellValue = String.valueOf(cell.getBooleanCellValue());
                break;
            }
            default: {
                cellValue = cell.getStringCellValue();
                break;
            }
        }
        return cellValue;
    }
    
    private static String getStreamCellValue(final Cell cell) {
        String cellValue = null;
        final StreamingCell sCell = (StreamingCell)cell;
        sCell.getCellType();
        switch (sCell.getCellTypeEnum()) {
            case STRING: {
                cellValue = sCell.getStringCellValue();
                break;
            }
            case NUMERIC: {
                cellValue = sCell.getStringCellValue();
                break;
            }
            case FORMULA: {
                cellValue = sCell.getStringCellValue();
                break;
            }
            case BOOLEAN: {
                cellValue = String.valueOf(sCell.getBooleanCellValue());
                break;
            }
            default: {
                cellValue = sCell.getStringCellValue();
                break;
            }
        }
        return cellValue;
    }
    
    private static <T> LinkedHashMap<Integer, Method> getMethodMap(final List<ExcelColumnModel> excelColumnModelList, final Class<T> tCls, final String methodNamePre) throws NoSuchMethodException, NoSuchFieldException {
        final LinkedHashMap<Integer, Method> methodMap = new LinkedHashMap<Integer, Method>();
        for (final ExcelColumnModel excelColumnModel : excelColumnModelList) {
            final String fieldName = excelColumnModel.getColEnName();
            try {
                final Field field = tCls.getDeclaredField(fieldName);
            }
            catch (NoSuchFieldException e) {
                try {
                    final Field field = tCls.getSuperclass().getDeclaredField(fieldName);
                }
                catch (NoSuchFieldException subE) {
                    final Field field = tCls.getSuperclass().getSuperclass().getDeclaredField(fieldName);
                }
            }
            final String getMethodName = new StringBuffer(methodNamePre).append(fieldName.substring(0, 1).toUpperCase()).append(fieldName.substring(1)).toString();
            Field field;
            final Method getMethod = "get".equals(methodNamePre) ? tCls.getMethod(getMethodName, (Class<?>[])new Class[0]) : tCls.getMethod(getMethodName, field.getType());
            methodMap.put(excelColumnModel.getColNo(), getMethod);
        }
        return methodMap;
    }
    
    private static <T> void invokeMethod(final T data, final Method method, final String value) throws InvocationTargetException, IllegalAccessException, ParseException {
        final Class[] clsArr = method.getParameterTypes();
        final Class cls = clsArr[0];
        final Object[] objArr = { null };
        Object obj;
        if (cls == BigDecimal.class) {
            obj = new BigDecimal(value);
        }
        else if (cls == Double.class) {
            obj = new Double(value);
        }
        else if (cls == Integer.class) {
            obj = new Integer(value);
        }
        else if (cls == Date.class) {
            obj = ((value.length() > 7) ? DateUtils.ISO_ON_DATE_FORMAT.parse(value) : DateUtils.ISO_ON_MONTH_FORMAT.parse(value));
        }
        else {
            obj = value;
        }
        method.invoke(data, obj);
    }
    
    private static LinkedHashMap<Integer, String> getColumnHeadMap(final List<ExcelColumnModel> excelColumnModelList) {
        final LinkedHashMap<Integer, String> columnHeadMap = new LinkedHashMap<Integer, String>();
        excelColumnModelList.forEach(excelColumnModel -> columnHeadMap.put(excelColumnModel.getColNo(), excelColumnModel.getColCnName()));
        return columnHeadMap;
    }
    
    private static LinkedHashMap<String, String> getColumnDescMap(final List<ExcelColumnModel> excelColumnModelList) {
        final LinkedHashMap<String, String> columnDescMap = new LinkedHashMap<String, String>();
        excelColumnModelList.forEach(excelColumnModel -> columnDescMap.put(excelColumnModel.getColEnName(), excelColumnModel.getColCnName()));
        return columnDescMap;
    }
    
    private static <T> void toExcel2007(final OutputStream out, final String title, final Collection<T> dataCollection, final ExcelModel excelModel) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, IOException, NoSuchFieldException {
        final XSSFWorkbook workbook = new XSSFWorkbook();
        try {
            final XSSFSheet sheet = workbook.createSheet(title);
            sheet.setDefaultColumnWidth(20);
            final XSSFCellStyle headStyle = workbook.createCellStyle();
            headStyle.setFillForegroundColor(new XSSFColor(Color.WHITE));
            headStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            headStyle.setBorderBottom(BorderStyle.THIN);
            headStyle.setBorderLeft(BorderStyle.THIN);
            headStyle.setBorderRight(BorderStyle.THIN);
            headStyle.setBorderTop(BorderStyle.THIN);
            headStyle.setAlignment(HorizontalAlignment.CENTER);
            final XSSFFont headFont = workbook.createFont();
            headFont.setBold(true);
            headFont.setFontName("\u9ed1\u4f53");
            headFont.setColor(new XSSFColor(Color.BLACK));
            headFont.setFontHeightInPoints((short)11);
            headStyle.setFont((Font)headFont);
            final XSSFCellStyle bodyStyle = workbook.createCellStyle();
            bodyStyle.setFillForegroundColor(new XSSFColor(Color.WHITE));
            bodyStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            bodyStyle.setBorderBottom(BorderStyle.THIN);
            bodyStyle.setBorderLeft(BorderStyle.THIN);
            bodyStyle.setBorderRight(BorderStyle.THIN);
            bodyStyle.setBorderTop(BorderStyle.THIN);
            bodyStyle.setAlignment(HorizontalAlignment.CENTER);
            bodyStyle.setVerticalAlignment(VerticalAlignment.CENTER);
            final XSSFFont bodyFont = workbook.createFont();
            bodyFont.setBold(false);
            bodyFont.setFontName("\u5b8b\u4f53");
            bodyStyle.setFont((Font)bodyFont);
            final List<ExcelColumnModel> excelColumnModelList = excelModel.getExcelColumnModelList();
            final XSSFRow row = sheet.createRow(0);
            final LinkedHashMap<Integer, String> columnHeadMap = getColumnHeadMap(excelColumnModelList);
            final Iterator<Map.Entry<Integer, String>> headIterator = columnHeadMap.entrySet().iterator();
            int columnCount = 0;
            while (headIterator.hasNext()) {
                final Map.Entry<Integer, String> head = headIterator.next();
                final XSSFCell headCell = row.createCell(columnCount);
                headCell.setCellStyle((CellStyle)headStyle);
                headCell.setCellValue((RichTextString)new XSSFRichTextString((String)head.getValue()));
                ++columnCount;
            }
            --columnCount;
            final T t = dataCollection.iterator().next();
            final Class tCls = t.getClass();
            final LinkedHashMap<Integer, Method> methodMap = getMethodMap(excelColumnModelList, (Class<Object>)tCls, "get");
            final Iterator<T> dataIterator = dataCollection.iterator();
            int dataCount = 0;
            while (dataIterator.hasNext()) {
                ++dataCount;
                final XSSFRow dataRow = sheet.createRow(dataCount);
                final T data = dataIterator.next();
                for (int i = 0; i <= columnCount; ++i) {
                    final XSSFCell dataCell = dataRow.createCell(i);
                    dataCell.setCellStyle((CellStyle)bodyStyle);
                    final Object value = methodMap.get(i).invoke(data, new Object[0]);
                    if (value != null) {
                        if (value instanceof Integer) {
                            dataCell.setCellValue((double)(int)value);
                        }
                        else if (value instanceof Long) {
                            dataCell.setCellValue(String.valueOf(value));
                        }
                        else if (value instanceof Float) {
                            dataCell.setCellValue(String.valueOf(value));
                        }
                        else if (value instanceof Double) {
                            dataCell.setCellValue((double)value);
                        }
                        else if (value instanceof Boolean) {
                            dataCell.setCellValue((boolean)value);
                        }
                        else if (value instanceof Date) {
                            dataCell.setCellValue(DateUtils.DEFAULT_ON_SECOND_FORMAT.format((Date)value));
                        }
                        else {
                            dataCell.setCellValue((RichTextString)new XSSFRichTextString(value.toString()));
                        }
                    }
                }
            }
            workbook.write(out);
        }
        catch (Exception e) {
            throw e;
        }
        finally {
            try {
                workbook.close();
            }
            catch (Exception ex) {}
        }
    }
    
    private static <T> void toExcel2003(final OutputStream out, final String title, final Collection<T> dataCollection, final ExcelModel excelModel) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, IOException, NoSuchFieldException {
        final HSSFWorkbook workbook = new HSSFWorkbook();
        try {
            final HSSFSheet sheet = workbook.createSheet(title);
            sheet.setDefaultColumnWidth(20);
            final HSSFCellStyle headStyle = workbook.createCellStyle();
            headStyle.setFillForegroundColor(HSSFColor.WHITE.index);
            headStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            headStyle.setBorderBottom(BorderStyle.THIN);
            headStyle.setBorderLeft(BorderStyle.THIN);
            headStyle.setBorderRight(BorderStyle.THIN);
            headStyle.setBorderTop(BorderStyle.THIN);
            headStyle.setAlignment(HorizontalAlignment.CENTER);
            final HSSFFont headFont = workbook.createFont();
            headFont.setBold(true);
            headFont.setFontName("\u9ed1\u4f53");
            headFont.setColor(HSSFColor.BLACK.index);
            headFont.setFontHeightInPoints((short)11);
            headStyle.setFont(headFont);
            final HSSFCellStyle bodyStyle = workbook.createCellStyle();
            bodyStyle.setFillForegroundColor(HSSFColor.WHITE.index);
            bodyStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            bodyStyle.setBorderBottom(BorderStyle.THIN);
            bodyStyle.setBorderLeft(BorderStyle.THIN);
            bodyStyle.setBorderRight(BorderStyle.THIN);
            bodyStyle.setBorderTop(BorderStyle.THIN);
            bodyStyle.setAlignment(HorizontalAlignment.CENTER);
            bodyStyle.setVerticalAlignment(VerticalAlignment.CENTER);
            final HSSFFont bodyFont = workbook.createFont();
            bodyFont.setBold(false);
            bodyFont.setFontName("\u5b8b\u4f53");
            bodyStyle.setFont(bodyFont);
            final List<ExcelColumnModel> excelColumnModelList = excelModel.getExcelColumnModelList();
            final HSSFRow row = sheet.createRow(0);
            final LinkedHashMap<Integer, String> columnHeadMap = getColumnHeadMap(excelColumnModelList);
            final Iterator<Map.Entry<Integer, String>> headIterator = columnHeadMap.entrySet().iterator();
            int columnCount = 0;
            while (headIterator.hasNext()) {
                final Map.Entry<Integer, String> head = headIterator.next();
                final HSSFCell headCell = row.createCell(columnCount);
                headCell.setCellStyle(headStyle);
                headCell.setCellValue((RichTextString)new HSSFRichTextString((String)head.getValue()));
                ++columnCount;
            }
            --columnCount;
            final T t = dataCollection.iterator().next();
            final Class tCls = t.getClass();
            final LinkedHashMap<Integer, Method> methodMap = getMethodMap(excelColumnModelList, (Class<Object>)tCls, "get");
            final Iterator<T> dataIterator = dataCollection.iterator();
            int dataCount = 0;
            while (dataIterator.hasNext()) {
                ++dataCount;
                final HSSFRow dataRow = sheet.createRow(dataCount);
                final T data = dataIterator.next();
                for (int i = 0; i <= columnCount; ++i) {
                    final HSSFCell dataCell = dataRow.createCell(i);
                    dataCell.setCellStyle(bodyStyle);
                    final Object value = methodMap.get(i).invoke(data, new Object[0]);
                    if (value != null) {
                        if (value instanceof Integer) {
                            dataCell.setCellValue((double)(int)value);
                        }
                        else if (value instanceof Long) {
                            dataCell.setCellValue(String.valueOf(value));
                        }
                        else if (value instanceof Float) {
                            dataCell.setCellValue(String.valueOf(value));
                        }
                        else if (value instanceof Double) {
                            dataCell.setCellValue((double)value);
                        }
                        else if (value instanceof Boolean) {
                            dataCell.setCellValue((boolean)value);
                        }
                        else if (value instanceof Date) {
                            dataCell.setCellValue(DateUtils.DEFAULT_ON_SECOND_FORMAT.format((Date)value));
                        }
                        else {
                            dataCell.setCellValue((RichTextString)new XSSFRichTextString(value.toString()));
                        }
                    }
                }
            }
            workbook.write(out);
        }
        catch (Exception e) {
            throw e;
        }
        finally {
            try {
                workbook.close();
            }
            catch (Exception ex) {}
        }
    }
    
    private static <T> void validate(final T data, final int rowNum, final Map<String, String> colDescMap, List<ExcelParseExceptionModel> parseExceptionModelList) {
        try {
            final Validator validator = ((HibernateValidatorConfiguration)Validation.byProvider((Class)HibernateValidator.class).configure()).failFast(false).buildValidatorFactory().getValidator();
            final Set<ConstraintViolation<T>> validateSet = (Set<ConstraintViolation<T>>)validator.validate((Object)data, new Class[0]);
            if (CheckUtil.isEmpty((Object)parseExceptionModelList) && CheckUtil.isNotEmpty((Object)validateSet)) {
                parseExceptionModelList = new ArrayList<ExcelParseExceptionModel>();
            }
            for (final ConstraintViolation<T> violation : validateSet) {
                final ExcelParseExceptionModel exceptionModel = new ExcelParseExceptionModel();
                final String fieldName = violation.getPropertyPath().toString();
                exceptionModel.setFieldName(fieldName);
                exceptionModel.setFieldDesc(colDescMap.get(fieldName));
                exceptionModel.setRowNum(rowNum);
                exceptionModel.setMessage(violation.getMessage());
                parseExceptionModelList.add(exceptionModel);
                System.out.println(violation.getMessage());
            }
        }
        catch (Throwable e) {
            ExcelUtil.log.error("\u62fc\u88c5\u7b2c{}\u884c\u5f02\u5e38\u4fe1\u606f\u53d1\u751fException:", (Object)rowNum, (Object)e);
        }
    }
    
    static {
        log = LoggerFactory.getLogger((Class)ExcelUtil.class);
    }
}
